import os
import logging
from django.utils import simplejson
from datetime import datetime
from google.appengine.ext import webapp
from google.appengine.ext import db
#from google.appengine.api import users
from google.appengine.api import memcache
from google.appengine.api import urlfetch
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from xml.dom import minidom 

from models import *
from helpers import *

class Armory(webapp.RequestHandler):
	""""""
	useragent =  "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070319 Firefox/2.0.0.3"
        def get(self,region,server,name):
		self.region = region.lower()
		self.realm = server.lower()
		self.name = name.lower()
		self.usecache = self.request.get("cache",default_value = 1)

                character = memcache.get(region +"-"+server+"-"+name)
                if character is not None and self.usecache == 1:
                    html = character
                else:
                    path = os.path.join(os.path.dirname(__file__), 'armory.html')
                    self.GetCharacter()
                    html = template.render(path, self.template_values)
                    if not memcache.add(region +"-"+server+"-"+name,html,time=3600):
                        if not memcache.replace(region +"-"+server+"-"+name,html,time=3600):
                            logging.error("Memcache set failed...")
                self.response.out.write(html)
        def GetCharacter(self):
                self.url = "http://"+self.region+".wowarmory.com/character-sheet.xml?r="+self.realm+"&n="+self.name
		q = db.GqlQuery("SELECT * FROM CharacterCache WHERE region = :1 AND realm = :2 AND name = :3", self.region,self.realm,self.name)
		cache_result = q.fetch(1)
        	if len(cache_result) > 0:
                        cache = cache_result[0]
                        dt = datetime.now() - cache.date
                        if self.usecache == 1 and dt.seconds <=43200:
                            self.Cached(cache)
                        else:
                            self.UnCached(cache)
		else:
			cache = CharacterCache()
                        self.UnCached(cache)

        def Cached(self, cache):
                self.template_values = simplejson.loads(cache.data)
                self.template_values["date"] = str(cache.date).split(".")[0]


        def UnCached(self,cache):
                self.content = self.GetXML()
		if self.content is not 0:
                    if self.content.getElementsByTagName('characterInfo')[0].hasAttribute('errCode'):
                        self.template_values  ={'error' :  "Suddenly the cave collapses. ", }
                    else:
                        self.template_values = self.GetTemplateValues(cache)
                else:
                    self.template_values = {'error' : "Something went wrong when fetching your precious character... " }

        def GetXML(self):
                try:
                    self.resp = urlfetch.fetch(self.url,headers = {'User-Agent':self.useragent})
                except Exception:
                    return 0
                if self.resp.status_code == 200:
                    return minidom.parseString(self.resp.content)
                else:
                    return 0

        def GetTemplateValues(self,cache):
                """Calls the XML parser functions and updates the cache. Returns template values"""
                cache.name = self.name
                cache.realm = self.realm
                cache.region = self.region
                self.GetBaseStats()
                self.GetSpellStats()
                self.GetMeleeStats()
                self.GetRangedStats()
                self.GetCharacterData()
                self.GetDefensiveStats()
                self.GetItems()
                template_values = {
                    'date': str(datetime.now()).split(".")[0],
                    'region': self.region,
                    'data': self.data,
                    'items':self.items,
                    'base': self.basestats,
                    'spell': self.spellstats,
                    'melee': self.meleestats,
                    'ranged': self.rangedstats,
                    'defense': self.defensivestats,
                }
                cache.data = simplejson.dumps(template_values)
                cache.put()
                return template_values
        def GetCharacterData(self):
		node = self.content.getElementsByTagName('character')[0]
		self.data = {
				'battleGroup': 	node.getAttribute('battleGroup'),
				'charUrl':      node.getAttribute('charUrl'),
				'class':        node.getAttribute('class'),
				'faction': 	node.getAttribute('faction'),
				'gender':	node.getAttribute('gender'),
				'guildName':	node.getAttribute('guildName'),
				'level':	node.getAttribute('level'),
				'name':		node.getAttribute('name'),
				'prefix':	node.getAttribute('prefix'),
				'suffix':	node.getAttribute('suffix'),
				'race':		node.getAttribute('race'),
				'realm':	node.getAttribute('realm'),
			}

	def GetItems(self):
		self.items = []
		for node in self.content.getElementsByTagName("item"):
			self.items.append({
				'Id': node.getAttribute('id'),				
				'icon': node.getAttribute('icon'),
				'gem0Id': node.getAttribute('gem0Id'),
				'gem1Id': node.getAttribute('gem1Id'),
				'gem2Id': node.getAttribute('gem2Id'),                                
				'slot': node.getAttribute('slot'),
			})
	def GetRangedStats(self):
		ranged = self.content.getElementsByTagName('ranged')[0]
		damage = ranged.getElementsByTagName('damage')[0]
		speed = ranged.getElementsByTagName('speed')[0]
		power = ranged.getElementsByTagName('power')[0]
		hit = ranged.getElementsByTagName('hitRating')[0]
		crit = ranged.getElementsByTagName('critChance')[0]
		self.rangedstats = {
					'damage': {
						'max': damage.getAttribute('max'),
						'min': damage.getAttribute('min'),
						'dps': damage.getAttribute('dps'),
						},
					'speed': {
						'hastePercent':speed.getAttribute('hastePercent'),
						'hasteRating': speed.getAttribute('hasteRating'),
						'value': speed.getAttribute('value'),
						},
					'power': {
						'base': power.getAttribute('base'),
						'effective': power.getAttribute('effective'),
						'increasedDps': power.getAttribute('increasedDps'),
						},
					'hitRating': {
						'increasedHit': hit.getAttribute('increasedHitPercent'),
						'penetration': hit.getAttribute('penetration'),
						'armorReduced': hit.getAttribute('reducedArmorPercent'),
						'value': hit.getAttribute('value'),
						},
					'critChance':{
						'percent': crit.getAttribute('percent'),
						'plusPercent': crit.getAttribute('plusPercent'),
						'rating': crit.getAttribute('rating'),
						},
				}
	def GetDefensiveStats(self):
		defenses = self.content.getElementsByTagName('defenses')[0]
		armor = defenses.getElementsByTagName('armor')[0]
		defense = defenses.getElementsByTagName('defense')[0]
		dodge = defenses.getElementsByTagName('dodge')[0]
		parry = defenses.getElementsByTagName('parry')[0]
		block = defenses.getElementsByTagName('block')[0]
		resilience = defenses.getElementsByTagName('resilience')[0]
		self.defensivestats = {
				'armor': {
					'effective': armor.getAttribute('effective'),
					'percent': armor.getAttribute('percent'),
					},
				'defense':{
					'value': defense.getAttribute('value'),
					},
				'dodge':{
					'percent': dodge.getAttribute('percent'),
					'rating': dodge.getAttribute('rating'),
					},
				'parry':{
					'percent': parry.getAttribute('percent'),
					'rating': parry.getAttribute('rating'),
					},
				'block':{
					'percent': block.getAttribute('percent'),
					'rating': block.getAttribute('rating'),
					},
				'resilience':{
					'value': resilience.getAttribute('value'),
					},
				}


	def GetMeleeStats(self):
		mainhand = self.content.getElementsByTagName('mainHandDamage')[0]
		offhand = self.content.getElementsByTagName('offHandDamage')[0]
		power = self.content.getElementsByTagName('melee')[0].getElementsByTagName('power')[0]
		hit = self.content.getElementsByTagName('melee')[0].getElementsByTagName('hitRating')[0]
		crit = self.content.getElementsByTagName('melee')[0].getElementsByTagName('critChance')[0]
		exp = self.content.getElementsByTagName('melee')[0].getElementsByTagName('expertise')[0]
		self.meleestats = {
				'mainhand': {
					'mindamage': mainhand.getAttribute('min'),
					'maxdamage': mainhand.getAttribute('max'),
					'dps': mainhand.getAttribute('dps'),
					'speed': mainhand.getAttribute('speed'),
					},
				'offhand': {
					'mindamage': offhand.getAttribute('min'),
					'maxdamage': offhand.getAttribute('max'),
					'dps': offhand.getAttribute('dps'),
					'speed': offhand.getAttribute('speed')
					},
				'power':{
					'base': power.getAttribute('base'),
					'eff': power.getAttribute('effective'),
					'dps': power.getAttribute('increasedDps'),
					},
				'hit': {
					'rating': hit.getAttribute('value'),
					'percent': hit.getAttribute('increasedHitPercent'),
					},
				'crit':{
					'rating': crit.getAttribute('rating'),
					'percent': crit.getAttribute('percent'),
					'increasedpercent': crit.getAttribute('plusPercent'),
					},
				'exp': {
					'rating': exp.getAttribute('rating'),
					'percent': exp.getAttribute('percent'),
					},

				}
	def GetBaseStats(self):

		self.basestats = {
				'strength': self.content.getElementsByTagName('strength')[0].getAttribute('effective'),
				'agility': self.content.getElementsByTagName('agility')[0].getAttribute('effective'),
				'stamina': self.content.getElementsByTagName('stamina')[0].getAttribute('effective'),
				'intellect': self.content.getElementsByTagName('intellect')[0].getAttribute('effective'),
				'spirit': self.content.getElementsByTagName('spirit')[0].getAttribute('effective'),
				'armor': self.content.getElementsByTagName('armor')[0].getAttribute('effective'),
			}
	def GetSpellStats(self):
		
		stats = self.content.getElementsByTagName('spell')[0]
                damage = stats.getElementsByTagName('bonusDamage')[0]
                hitrating = stats.getElementsByTagName('hitRating')[0]
                hasterating = stats.getElementsByTagName('hasteRating')[0]
                critchance = stats.getElementsByTagName('critChance')[0]
                manaregen = stats.getElementsByTagName('manaRegen')[0]
		self.spellstats = {
			'bonusDamage':{
				'arcane': damage.getElementsByTagName('arcane')[0].getAttribute('value'),
				'fire':   damage.getElementsByTagName('fire')[0].getAttribute('value'),
				'frost':  damage.getElementsByTagName('frost')[0].getAttribute('value'),
				'holy':   damage.getElementsByTagName('holy')[0].getAttribute('value'),
				'nature': damage.getElementsByTagName('nature')[0].getAttribute('value'),
				'shadow': damage.getElementsByTagName('shadow')[0].getAttribute('value')
			},
			'bonusHealing':   stats.getElementsByTagName('bonusHealing')[0].getAttribute('value'),
			'hitRating' : {
				'value':       hitrating.getAttribute('value'),
				'percent':     hitrating.getAttribute('increasedHitPercent'),
				'penetration': hitrating.getAttribute('penetration')
				},
			'hasteRating':{
				'rating':  hasterating.getAttribute('hasteRating'),
				'percent': hasterating.getAttribute('hastePercent')
				},
			'critChance':{
				'rating': critchance.getAttribute('rating'),
				'arcane': critchance.getElementsByTagName('arcane')[0].getAttribute('percent'),
				'fire':   critchance.getElementsByTagName('fire')[0].getAttribute('percent'),
				'frost':  critchance.getElementsByTagName('frost')[0].getAttribute('percent'),
				'holy':   critchance.getElementsByTagName('holy')[0].getAttribute('percent'),
				'nature': critchance.getElementsByTagName('nature')[0].getAttribute('percent'),
				'shadow': critchance.getElementsByTagName('shadow')[0].getAttribute('percent'),
				},
			'manaRegen':{
				'casting':    manaregen.getAttribute('casting'),
				'notcasting': manaregen.getAttribute('notCasting'),
				}
		}
		

class MainPage(webapp.RequestHandler):
	def get(self):
		template_values = {}
		path = os.path.join(os.path.dirname(__file__), 'index.html')
		self.response.out.write(template.render(path, template_values))
class AboutPage(webapp.RequestHandler):
        def get(self):
                template_values = {}
                path = os.path.join(os.path.dirname(__file__), 'about.html')
                self.response.out.write(template.render(path, template_values))
            
app_bindings =[('/', MainPage),(r'/(.*)/(.*)/(.*)', Armory)]
app_bindings.append(('/icon', GetIcon))
app_bindings.append(('/tooltip', ItemToolTip))
app_bindings.append(('/about', AboutPage))
application = webapp.WSGIApplication(app_bindings, debug=False)

def main():
	run_wsgi_app(application)

if __name__ == "__main__":
	main()

#don giv a fUK
